﻿using Client;
using Shared.Method;
using Shared.Model;
using Shared.SoftMethod;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using Tools.Dialog;

namespace Tools
{
    public partial class FormCmdTools : Form
    {
        private string _localIp, _modemIp;
        private string _username, _password;
        private int _localPort;
        private int _nodeId;
        private string _online;
        private string _messageOn;
        private YcdTelnetSecond _ycdTel = null;
        private Device_Data _device = null;
        private PropertyInfo[] _listInfo = null;
        private string _softType = "0";
        private Point _localPoint;

        private readonly string CMD_FILE = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "cmd.txt";//保存包装数据


        public FormCmdTools(string ip, int port, Point point)
        {
            _localIp = ip;
            _localPort = port;
            _localPoint = point;
            this.Location = _localPoint;
            InitializeComponent();
        }

        private void richTextBoxMsg_TextChanged(object sender, EventArgs e)
        {
            richTextBoxMsg.SelectionStart = richTextBoxMsg.Text.Length;
            richTextBoxMsg.ScrollToCaret();
        }

        //将信息写入信息窗口
        private void AppendRichTextBox(string value)
        {
            if (this.richTextBoxMsg.InvokeRequired)
            {
                Action<string> d = new Action<string>(AppendRichTextBox);
                Invoke(d, new object[] { value });
            }
            else
            {
                if (value == null) return;

                value = value.Replace("\0", "");
                this.richTextBoxMsg.AppendText(value + "\r\n");

            }
        }

        private void ClearText(Control con)
        {
            if (this.InvokeRequired)
            {
                Action<Control> d = new Action<Control>(ClearText);
                Invoke(d, con);
            }
            else
            {
                con.Text = null;
            }
        }

        /// <summary>
        /// 设置对象颜色
        /// </summary>
        /// <param name="con"></param>
        /// <param name="text"></param>
        /// <param name="col"></param>
        private void SetControlText(Control con, string text, Color col)
        {
            if (this.InvokeRequired)
            {
                Action<Control, string, Color> d = new Action<Control, string, Color>(SetControlText);
                Invoke(d, con, text, col);
            }
            else
            {
                con.BackColor = col;
                if (string.IsNullOrEmpty(text) == false)
                    con.Text = text;
            }
        }

        private void FormCmdTools_Load(object sender, EventArgs e)
        {

#if false
            HttpArgs args = new HttpArgs()
            {
                Host = "192.168.1.1",
                Url = "/admin/login.asp",
            };

            HttpBaseClass.GetHttpMsg("192.168.1.213", 23457, "192.168.1.1", 80, args, "OK", out string oMsg, HttpBaseClass.HttpMethod.GET);

            string pattern = @"csrfmiddlewaretoken.+/>";
            var match = Regex.Match(oMsg, pattern);
            string csrftoken = match.Value.Substring(match.Value.IndexOf('=') + 2, 32);


            pattern = @"csrftoken.+/>";
            var match2 = Regex.Match(oMsg, pattern);
            string wareToken = match2.Value.Substring(match2.Value.IndexOf('=') + 2, 32);

            args.Url = "/boaform/admin/formLogin";
            args.Host = "192.168.1.1";
            args.Body = string.Format("username2=user&psd2=&username1={0}&psd1={1}&csrfmiddlewaretoken={2}&username={0}&psd={1}&csrftoken={3}"
                , "CMCCAdmin"
                , "aDm8H%MdA"
                , wareToken
                , csrftoken);

            HttpBaseClass.GetHttpMsg("192.168.1.213", 23450, "192.168.1.1", 80, args, "OK", out oMsg, HttpBaseClass.HttpMethod.POST);


#endif
            //获取配置命令和循环执行命令
            //_localIp = AppSetting.GetValue("LocalIp");
            _modemIp = AppSetting.GetValue("ModemIp");
            _online = AppSetting.GetValue("Online");
            _username = AppSetting.GetValue("UserName");
            _password = AppSetting.GetValue("Password");
            _messageOn = AppSetting.GetValue("MessageOn");

            _softType = AppSetting.GetValue("SoftType");
            //int.TryParse(AppSetting.GetValue("LocalPort"), out _localPort);
            int.TryParse(AppSetting.GetValue("NodeId"), out _nodeId);

            if (string.IsNullOrEmpty(_localIp)
                || string.IsNullOrEmpty(_modemIp)
                || string.IsNullOrEmpty(_username)
                || string.IsNullOrEmpty(_password)
                || _localPort <= 0)
            {
                MessageBox.Show("参数错误");
                Close();
                return;
            }

            //_softType = "3";

            string version = Application.ProductVersion.ToString();

            if (_softType == "0")
                this.Text = string.Format("友创达命令编辑器V{0} 【{1}】", version, _localIp);
            else if (_softType == "1")
                this.Text = string.Format("友创达温补软件定制版V{0} 【{1}】", version, _localIp);
            else if (_softType == "2")
                this.Text = string.Format("友创达跳站专用版软件V{0} 【{1}】", version, _localIp);
            else if (_softType == "3")
                this.Text = string.Format("客退返修专用信息写入软件V{0} 【{1}】", version, _localIp);
            //else if (_softType == "4")
            //    this.Text = string.Format("广电信息写入V{0} 【{1}】", version, _localIp);
            //else if (_softType == "5")
            //    this.Text = string.Format("广电信息检查V{0} 【{1}】", version, _localIp);
            else
            {
                MessageBox.Show("软件类型配置错误");
                Close();
            }

            //读取命令配置文件
            if (File.Exists(CMD_FILE) == false)
            {
                var file = File.Create(CMD_FILE);
                file.Close();
                MessageBox.Show("创建cmd.txt成功，请配置好命令后重启");
                Close();
                return;
            }

            string fileStr = null;

            using (var stream = File.OpenText(CMD_FILE))
            {
                fileStr = stream.ReadToEnd();
            }

            //MessageBox.Show(cmdStr);
            //分拆CMD命令

            /*#打头为注释
             * 0，为http命令，1为telnet命令，格式为：0,cmdStr,keyword
             * 数据以逗号分隔，不同数据之前以回车符间隔
             * */

            List<CmdClass> listCmd = GetCmdClass(fileStr);

            if (listCmd == null || listCmd.Count == 0)
            {
                MessageBox.Show("解析命令失败，请检查cmd.txt文件");
                Close();
                return;
            }

            _listInfo = typeof(Device_Data).GetProperties();

            //循环执行指令和命令
            Task.Factory.StartNew(() =>
            {
                while (true)
                {
                    //关闭TELNET
                    _ycdTel?.Send("exit");
                    _ycdTel?.Close();
                    _ycdTel = null;

                    AppendRichTextBox("等待光猫断开连接");

                    while (true)
                    {
                        if (ArpBaseClass.IsIpEnabled(_localIp) == false) break;
                        System.Threading.Thread.Sleep(1000);
                    }

                    while (true)
                    {
                        if (PingBaseClass.PingTest(_localIp, _modemIp) == false) break;
                        System.Threading.Thread.Sleep(1000);
                    }

                    ClearText(this.richTextBoxMsg);
                    AppendRichTextBox("等待连接……");
                    SetControlText(this.labelShow, "WAIT", this.BackColor);

                    //SoftShared.SetControl(this, this.labelShow, "TESTING", Color.Red);
                    //SoftShared.SetControlEnable(this, this.button1, false);

                    //检查光猫是否连接
                    int pingOkTimes = 0;
                    for (int i = 0; i < 90; i++)
                    {
                        if (PingBaseClass.PingTest(_localIp, _modemIp))
                        {
                            pingOkTimes++;
                        }
                        else
                        {
                            pingOkTimes = 0;
                        }

                        if (pingOkTimes >= 4)
                            break;

                        System.Threading.Thread.Sleep(500);
                    }

                    if (pingOkTimes < 4)
                    {
                        AppendRichTextBox("未能成功PING通光猫");
                        continue;
                    }

                    System.Threading.Thread.Sleep(2000);

                    string mac = ArpBaseClass.GetMacFromIp(_localIp, _modemIp);

                    if (string.IsNullOrEmpty(mac))
                    {
                        AppendRichTextBox("未能获取MAC地址");
                        continue;
                    }

                    AppendRichTextBox("MAC：" + mac);

                    bool runRet = true;

                    #region 处理温补回显

                    if (_softType == "1")
                    {
                        runRet = HandleWifiCheck(mac);

                        //continue;
                    }
                    #endregion

                    #region 调整站位

                    else if (_softType == "2")
                    {
                        runRet = HandleNode(mac);
                        //continue;
                    }

                    #endregion

                    #region 专门处理客退返修板

                    else if (_softType == "3")
                    {
                        runRet = HandleModem(mac);
                        //continue;
                    }

                    #endregion

                    //#region 广电信息写入
                    //else if (_softType == "4")
                    //{
                    //    HandleWriteTelevision(mac);
                    //}
                    //#endregion

                    //#region 广电BOB检查
                    //else if (_softType == "5")
                    //{
                    //    HandleBobInspect();
                    //}
                    //#endregion

                    else
                    {

                        if (_online == "1")//在线才会去取Device数据
                        {
                            _device = null;//防止出现写入的是之前的MAC地址
                            Device_Data deviceW = new Device_Data();
                            deviceW.SetWhere();
                            deviceW.MACAddr = mac;
                            var selectDevice = MethodWcf.SelectDeviceDataClient(deviceW);
                            if (selectDevice.result)
                            {
                                _device = selectDevice.value[0];
                                AppendRichTextBox("获取Device数据成功");
                            }
                            else
                            {
                                AppendRichTextBox("获取Device数据失败");
                                continue;
                            }

                            //移动增加网页登录流程
                            if (_device.DeviceType.Contains("CMCC"))
                            {
                                //LoginCMCC();
                                SoftShared.LoginCMCC(_modemIp, _localIp, _localPort, ref portOffset, _device.HW_PROVINCE_NAME);
                            }

                        }

                        for (int i = 0; i < listCmd.Count; i++)
                        {
                            for (int j = 0; j < listCmd[i].RunTimes; j++)
                            {
                                runRet = RunCmd(listCmd[i], mac);

                                if (listCmd[i].Continue == "F")//如果F，表示FALSE继续
                                {
                                    runRet = !runRet;
                                }

                                if (runRet) break;
                            }

                            if (runRet == false) break;
                        }

                    }

                    if (_messageOn == "1")
                        MessageBox.Show("运行结果为：" + runRet + "，点击确定继续运行");

                    string message;
                    if (runRet)
                    {
                        SetControlText(this.labelShow, "PASS", Color.Green);
                        _ycdTel?.SendAndRecv("mpctl led on", "#", out message);
                    }
                    else SetControlText(this.labelShow, "FAIL", Color.Red);
                }

            });

        }

        //private bool HandleWriteTelevision(string mac)
        //{
        //    //获取MAC地址，如果是默认的MAC，则要求扫描
        //    if (string.IsNullOrEmpty(mac) || mac == "00E04C867001")
        //    {
        //        mac = FormClass.GetEnterMac(new Point(this.Location.X, this.Location.Y + 10));
        //        if (string.IsNullOrEmpty(mac)) { AppendRichTextBox("输入MAC地址为空"); return false; }
        //    }

        //    return true;
        //}

        //private void HandleBobInspect()
        //{
        //    throw new NotImplementedException();
        //}

        private bool HandleWifiCheck(string mac, YcdTelnetSecond tel = null)
        {
            if (tel == null) _ycdTel = TelnetModem();
            else _ycdTel = tel;

            if (_ycdTel == null)
            {
                AppendRichTextBox("TELNET光猫失败");
                return false;
            }

            string message;//返回信息

            //_ycdTel.Send(new byte[] { 0x03 });
            //_ycdTel.SendAndRecv("", "#", out message);
            //AppendRichTextBox(message);

            //关闭长发光
            _ycdTel.SendAndRecv("flash set USER_FACTORY_BEFORE_RUN 0", "#", out message, 6000);
            AppendRichTextBox(message);

            //添加指令
            _ycdTel.SendAndRecv("killall -9 getse", "#", out message, 6000);
            AppendRichTextBox(message);
            _ycdTel.SendAndRecv("cat /proc/kmsg &", "#", out message, 6000);
            AppendRichTextBox(message);
            _ycdTel.SendAndRecv("getse &", "#", out message, 6000);
            AppendRichTextBox(message);
            _ycdTel.SendAndRecv("echo 0 > /proc/luna_watchdog/watchdog_flag", "#", out message, 6000);
            AppendRichTextBox(message);
            _ycdTel.SendAndRecv("echo 0 > /proc/sys/kernel/softlockup_panic", "#", out message, 6000);
            AppendRichTextBox(message);
            _ycdTel.SendAndRecv("ifconfig wlan0 down", "#", out message, 6000);
            AppendRichTextBox(message);
            _ycdTel.SendAndRecv("iwpriv wlan0 set_mib phyBandSelect=1", "#", out message, 6000);
            AppendRichTextBox(message);
            _ycdTel.SendAndRecv("iwpriv wlan0 set_mib mp_specific=1", "#", out message, 6000);
            AppendRichTextBox(message);
            _ycdTel.SendAndRecv("iwpriv wlan0 set_mib ther=0", "#", out message, 6000);
            AppendRichTextBox(message);
            _ycdTel.SendAndRecv("ifconfig wlan0 up", "#", out message, 6000);
            AppendRichTextBox(message);
            _ycdTel.SendAndRecv("iwpriv wlan0 mp_start", "#", out message, 6000);
            AppendRichTextBox(message);
            _ycdTel.SendAndRecv("iwpriv wlan0 get_mib mp_specific", "#", out message, 6000);
            AppendRichTextBox(message);
            _ycdTel.SendAndRecv("iwpriv wlan0 mp_ant_tx a", "#", out message, 6000);
            AppendRichTextBox(message);
            _ycdTel.SendAndRecv("iwpriv wlan0 mp_channel 3", "#", out message, 6000);
            AppendRichTextBox(message);
            _ycdTel.SendAndRecv("iwpriv wlan0 mp_bandwidth 40M=1,shortGI=0", "#", out message, 6000);
            AppendRichTextBox(message);
            _ycdTel.SendAndRecv("iwpriv wlan0 mp_rate 135", "#", out message, 6000);
            AppendRichTextBox(message);
            _ycdTel.SendAndRecv("iwpriv wlan0 mp_ctx background,pkt", "#", out message, 6000);
            AppendRichTextBox(message);
            //tel.SendAndRecv("\r\n","#",out message,6000);
            //AppendRichTextBox(message);
            //添加10S时间
            AppendRichTextBox("等待10秒");
            System.Threading.Thread.Sleep(10000);

            //var result = tel.SendAndRecv("iwpriv wlan0 mp_start", "#", out message);
            //AppendRichTextBox(message);
            //if (result == false)
            //{
            //    AppendRichTextBox("WIFI指令1，失败");
            //    return false;
            //}

            var result = _ycdTel.SendAndRecv("iwpriv wlan0 mp_ther", "mp_ther:", out message);
            AppendRichTextBox(message);
            //result = TelnetSendAndRecv("iwpriv wlan0 mp_ther", "#", out message);
            if (result == false)
            {
                AppendRichTextBox("WIFI指令2，失败");
                return false;
            }

            //获取数字
            var keyMsgs = message.Replace("\n", "").Split('\r');

            var numStr = (from s in keyMsgs
                          where s.Length >= 1 && s.Length <= 3
                          select s).FirstOrDefault();

            int number = 0;

            if (int.TryParse(numStr, out number))
            {
                result = _ycdTel.SendAndRecv("flash set HW_WLAN0_11N_THER " + (number + 1), "=" + (number + 1), out message, 6000);
                AppendRichTextBox(message);
                if (result)
                {
                    AppendRichTextBox("写WIFI温补成功");

                    return true;
                }
                else
                {
                    AppendRichTextBox("写WIFI温补失败");
                }
            }
            else
            {
                AppendRichTextBox("获取WIFI温补值失败");
            }

            return false;
        }

        #region OLT测试

        //List<OnuMsg> _listOnu = new List<OnuMsg>();//所有ONU
        private Queue<OnuMsg> _queueOnu = new Queue<OnuMsg>();//存储需要注册的ONU
        private OnuMsg _onuMack = null;

        private void OLTRegion()
        {
            var showMsg = new FormShowMessage(new System.Drawing.Point(this.Location.X + this.Width, this.Location.Y));
            showMsg.Show();

            Task.Factory.StartNew(() =>
            {
                var tel = TelnetModem();

                if (tel == null)
                {
                    MessageBox.Show("TELNET OLT失败，请检查用户名、密码、OLT的IP");
                    Application.Exit();//关闭软件
                    return;
                }

                //var showOk = new FormShowOk();
                //showOk.Show();

                int runtimes = 0;
                while (true)//循环执行telnet指令
                {
                    ClearText(this.richTextBoxMsg);

                    string msg;

                    //判断ONU
                    bool runRet = TelnetControlCmd(2, "show gpon onu state\r\n", "#", out msg, tel);

                    AppendRichTextBox(msg);

                    //打开提示窗口，显示PASS
                    //关闭提示窗口
                    var listState = GetListStr(msg);

                    if ((runtimes >= 4 || _onuMack == null)
                    && _queueOnu.Count > 0
                    && (_onuMack = _queueOnu.Dequeue()) != null)
                    {

                        EnterLevel(2, tel, null);

                        TelnetControlCmd(3, "registration-method sn " + _onuMack.OnuSn, "#", out msg, tel, "interface " + _onuMack.OnuName);
                        AppendRichTextBox(msg);

                        runtimes = 0;
                    }

                    if (listState != null && listState.Length > 0)
                    {

                        string printMsgStr = string.Empty;

                        var listPrint = (from s in listState
                                         where s.Contains("working") || s.Contains("syncMib")
                                         select s).ToList();

                        if (listPrint.Count > 0)
                            for (int j = 0; j < listPrint.Count; j++)
                            {
                                printMsgStr += listPrint[j].Trim() + "\r\n";
                                if (_onuMack != null && listPrint[j].Contains(_onuMack.OnuName)) _onuMack = null;
                            }

                        showMsg.SetTextBox(printMsgStr);
                    }

                    runRet = TelnetControlCmd(2, "show gpon onu uncfg", "#", out msg, tel);

                    AppendRichTextBox(msg);

                    //获取ONU的接口信息
                    var listUncfg = GetListStr(msg);

                    if (listUncfg != null && listUncfg.Length > 0)
                    {
                        for (int i = 0; i < listUncfg.Length; i++)
                        {
                            //将信息文本格式化
                            while (listUncfg[i].Contains("  ")) listUncfg[i] = listUncfg[i].Replace("  ", " ");
                            var portMsg = listUncfg[i].Split(' ');

                            if (portMsg.Length < 3) continue;

                            var onu = new OnuMsg();
                            onu.OnuName = portMsg[0].Trim();
                            onu.OnuSn = portMsg[1].Trim();

                            _queueOnu.Enqueue(onu);
                        }
                    }

                    runtimes++;
                    System.Threading.Thread.Sleep(3000);//等待3秒
                }
            });
        }

        private string[] GetListStr(string msg)
        {
            string[] listMsg = null;
            try
            {
                if (msg.Contains("----") == false) return listMsg;

                int start = msg.LastIndexOf("----");
                int end = msg.LastIndexOf("\r");
                if (start != -1 && end != -1)
                {
                    listMsg = msg.Substring(start + 4, end - start - 1).Trim().Split('\r');
                }
            }
            catch (Exception ex)
            {
                AppendRichTextBox(ex.ToString());
            }
            return listMsg;
        }

        private int GetLevel(YcdTelnetSecond tel)
        {
            //获取当前TELNET级别
            string msg;

            tel.SendAndRecv("\r\n", "#", out msg);

            int localLevel = 1;
            if (msg.Contains("(config)#")) localLevel = 2;
            else if (msg.Contains("(config-if)#")) localLevel = 3;

            return localLevel;
        }

        private bool EnterLevel(int level, YcdTelnetSecond tel, string levelCmdStr)
        {
            try
            {
                if (tel == null || tel.Connected == false) tel = TelnetModem();

                if (tel == null) { MessageBox.Show("TELNET 光猫失败"); return false; }

                int localLevel = GetLevel(tel);

                string msg;
                if (localLevel > level)
                {
                    //退一到两个级别
                    for (int i = 0; i < localLevel - level; i++)
                    {
                        tel.SendAndRecv("exit\r\n", "#", out msg);
                        AppendRichTextBox(msg);
                    }
                }
                else if (localLevel < level)
                {
                    if (localLevel == 1) { tel.SendAndRecv("configure terminal", "#", out msg); AppendRichTextBox(msg); }//转到2阶
                    if (level == 3) { tel.SendAndRecv(levelCmdStr, "#", out msg); AppendRichTextBox(msg); }//转到3阶
                }

                localLevel = GetLevel(tel);

                if (localLevel == level)
                    return true;
                else
                    return false;
            }
            catch (Exception ex)
            {
                AppendRichTextBox(ex.ToString());
                return false;
            }
        }


        private bool TelnetControlCmd(int level, string cmdStr, string keyWord, out string cmdMsg, YcdTelnetSecond tel, string levelCmdStr = null)
        {
            cmdMsg = string.Empty;

            try
            {
                string msg;

                if (EnterLevel(level, tel, levelCmdStr))
                {
                    var runRet = tel.SendAndRecv(cmdStr, keyWord, out msg);
                    cmdMsg = msg;
                    if (runRet == false) return false;
                    else return true;
                }
                else
                {
                    return false;
                }

                //if (tel == null || tel.Connected == false) tel = TelnetModem();

                //if (tel == null) { MessageBox.Show("TELNET 光猫失败"); return false; }

                //int localLevel = GetLevel(tel);


                //if (localLevel > level)
                //{
                //    //退一到两个级别
                //    for (int i = 0; i < localLevel - level; i++)
                //    {
                //        tel.SendAndRecv("exit", "#", out msg);
                //        AppendRichTextBox(msg);
                //    }
                //}
                //else if (localLevel < level)
                //{
                //    if (localLevel == 1) { tel.SendAndRecv("configure terminal", "#", out msg); AppendRichTextBox(msg); }//转到2阶
                //    if (level == 3) { tel.SendAndRecv(levelCmdStr, "#", out msg); AppendRichTextBox(msg); }//转到3阶
                //}

                //localLevel = GetLevel(tel);

                //if (localLevel == level)
                //{
                //    var runRet = tel.SendAndRecv(cmdStr, keyWord, out msg);
                //    //AppendRichTextBox(msg);
                //    cmdMsg = msg;
                //    if (runRet == false) return false;
                //    else return true;
                //}
                //else
                //{
                //    AppendRichTextBox("跳转到相应的命名级别失败");
                //    MessageBox.Show("跳转到相应的命名级别失败");
                //    return false;
                //}
            }
            catch (Exception ex)
            {
                AppendRichTextBox(ex.ToString());
                return false;
            }
        }

        #endregion

        /// <summary>
        /// 初始化光猫到客退返修
        /// </summary>
        /// <param name="mac"></param>
        private bool HandleModem(string mac)
        {
            /*状态可以分为如下几种：
             * 1、老系统的产品，有MAC地址==>创建一条产品信息到新系统，绑定一个内部MAC
             * 2、老系统的产品，无MAC地址（换过FLASH）==>创建一条产品信息，绑定一个内部MAC，写MAC地址
             * 3、新系统的产品，有MAC地址==>将站位调整到客退专用流程
             * 4、新系统的产品，无MAC地址（换FLASH）==>将站位调整到客退专用流程，写MAC
             * */
            bool hasMac = true;

            if (string.IsNullOrEmpty(mac) || mac == "00E04C867001")
            {
                //查询不到相关的MAC地址信息，则提示扫入MAC地址
                hasMac = false;
                mac = FormClass.GetEnterMac(new Point(this.Location.X, this.Location.Y + 10));
                if (string.IsNullOrEmpty(mac)) { AppendRichTextBox("输入MAC地址为空"); return false; }
            }

            Device_Data deviceW = new Device_Data();
            deviceW.SetWhere();
            deviceW.MACAddr = mac;
            var selectDevice = MethodWcf.SelectDeviceDataClient(deviceW);

            if (selectDevice.result == false)
            {
                AppendRichTextBox("无法在数据库中查到相应的产品信息；\r\n请写入MAC后重试");
                return false;
            }

            _ycdTel = null;

            if (hasMac == false)
            {
                //需要写一个MAC地址
                _ycdTel = TelnetModem();

                if (_ycdTel == null) { return false; }
                string msg;

                //XPON型号
                string ponMode = null;

                if (selectDevice.value[0].PONType == "STIA")
                {
                    ponMode = "1";
                    //写BOB信息
                    _ycdTel.Send("prolinecmd bobinfo UX GPON write 0 &\r\n");

                    _ycdTel.SendAndRecv("flash set GPON_SN FHTT002460E2", "=FHTT002460E2", out msg);
                    AppendRichTextBox("写GPON_SN成功,SN:FHTT002460E2");
                }
                else
                {
                    ponMode = "2";
                    //写BOB初始化信息
                    _ycdTel.Send("prolinecmd bobinfo UX EPON write 0 &\r\n");
                }

                //写PON_MODE
                _ycdTel.SendAndRecv(string.Format("flash set PON_MODE {0}", ponMode), "=" + ponMode, out msg);
                AppendRichTextBox("写PON_MODEM成功，PONMODE：" + ponMode);

                _ycdTel.SendAndRecv(string.Format("flash set ELAN_MAC_ADDR {0}", mac), "=" + mac, out msg);
                AppendRichTextBox("写MAC地址成功，MAC：" + mac);
            }

            //写WIFI温补值
            var handleWifi = HandleWifiCheck(mac, _ycdTel);

            if (handleWifi == false)
            {
                AppendRichTextBox("写温补值失败");
                return false;
            }

            //查询数据库中PRODUCT表是否有对应的数据
            PRODUCT proW = new PRODUCT();
            proW.SetWhere();
            proW.MAC = mac;

            var selectProduct = MethodWcf.SelectProductClient(proW);

            if (selectProduct.result == false)
            {
                //产品是老系统的产品，创建一条产品信息，放在5019产线上
                PRODUCT product = new PRODUCT();
                product.SetUpdate();
                product.MAC = mac;
                product.YCD_MAC = MethodWcf.GetYcdMacClient(selectDevice.value[0].PONType);
                product.FLOW_ID = 123;
                product.LINE_ID = 5019;
                product.NODE_ID = 20083;
                product.TEST_RESULT = "Y";
                product.START_TIME = DateTime.Now;
                product.STATE = false;
                product.NODE_STATE = true;
                //product.BREAK_STATE = false;//标记为客退返工产品

                MethodWcf.InsertProductClient(product);//写入产品信息
            }
            else if (selectProduct.value[0].NODE_ID == 20072
                || selectProduct.value[0].NODE_ID == 20089
                || selectProduct.value[0].FLOW_ID == 123)
            {
                //产品是新系统产品，修改站位信息，判断是否已经是出货检查的商品了
                PRODUCT proU = new PRODUCT();
                proU.SetWhere();
                proU.MAC = mac;
                proU.SetUpdate();
                proU.FLOW_ID = 123;
                proU.LINE_ID = 5019;
                proU.NODE_ID = 20083;
                proU.TEST_RESULT = "Y";
                //proU.START_TIME = DateTime.Now;
                proU.STATE = false;
                proU.NODE_STATE = true;
                //proU.BREAK_STATE = false;//标记为客退返工产品

                MethodWcf.UpdateProductClient(proU);
            }
            else
            {
                //不是出货的产品，不能够进入客退返修流程
                AppendRichTextBox("此产品不是客退品，请检查是否混料了");
                return false;
            }

            AppendRichTextBox("初始化客退返修产品成功");

            return true;

        }

        int _portOffset = DateTime.Now.Second;

        /// <summary>
        /// 连接并登陆光猫，返回类，若为空则链接失败
        /// </summary>
        /// <returns></returns>
        private YcdTelnetSecond TelnetModem()
        {
            //使用新的类YcdTelnetSecond
            if (_portOffset >= 500) _portOffset = 0;
            _portOffset++;

            YcdTelnetSecond telnet = new YcdTelnetSecond(_modemIp, _localIp, _localPort + _portOffset);

            //连续登录5次，间隔5秒
            for (int i = 0; i < 5; i++)
            {
                if (telnet.Connect()) break;
                else if (i == 4) return null;//连续登录5次失败

                System.Threading.Thread.Sleep(5000);
            }

            //if (bOnlyConnect)
            //{
            //    return telnet;
            //}


            bool telRet = false;

            AppendRichTextBox("输入用户名称……");
            if (telnet.SendAndRecv(_username, "password", out _))
            {
                AppendRichTextBox("输入用户密码……");
                if (telnet.SendAndRecv(_password, ">", out string msg2) || msg2.Contains("#"))
                {
                    AppendRichTextBox("登录成功");
                    telRet = true;
                }
            }

            if (telRet == false) { AppendRichTextBox("登录失败"); return null; }

            return telnet;
        }

        private YcdTelnetSecond TelnetModemTelevision()
        {
            //使用新的类YcdTelnetSecond
            if (_portOffset >= 500) _portOffset = 0;
            _portOffset++;

            YcdTelnetSecond telnet = new YcdTelnetSecond(_modemIp, _localIp, _localPort + _portOffset);

            //连续登录5次，间隔5秒
            for (int i = 0; i < 5; i++)
            {
                if (telnet.Connect()) break;
                else if (i == 4) return null;//连续登录5次失败

                System.Threading.Thread.Sleep(5000);
            }

            return telnet;
        }

        /// <summary>
        /// 跳站部分
        /// </summary>
        /// <param name="mac"></param>
        private bool HandleNode(string mac)
        {
            _ycdTel = TelnetModem();

            if (_ycdTel == null)
            {
                AppendRichTextBox("TELNET光猫失败\r\nTELNET光猫失败\r\nTELNET光猫失败\r\nTELNET光猫失败\r\nTELNET光猫失败\r\nTELNET光猫失败\r\n");
                return false;
            }

            //写TEMP MAC
            SoftShared.SetTempMsg(_ycdTel, out _);

            if (_nodeId != 20063 && _nodeId != 20065 /*&& _nodeId != 20079 && _nodeId != 20069*/)
            {
                _nodeId = 20063;
            }

            //判断MAC是否有对应的SN号码，若有则不可以跳站
            PRODUCT_SN snW = new PRODUCT_SN();
            snW.SetWhere();
            snW.MAC = mac;
            var selectSnCount = MethodWcf.SelectProductSnCountClient(snW);
            if (selectSnCount.message != "0")
            {
                AppendRichTextBox("此MAC绑定了SN号码，不可以跳站\r\n此MAC绑定了SN号码，不可以跳站\r\n此MAC绑定了SN号码，不可以跳站\r\n此MAC绑定了SN号码，不可以跳站\r\n此MAC绑定了SN号码，不可以跳站\r\n此MAC绑定了SN号码，不可以跳站!!!!!");
                return false;
            }

            //write inside mac
#if false
            if (mac.Contains("FCDE") == false
                && mac.Contains("FCDF") == false)
            {
                string sql = $"SELECT YCD_MAC FROM PRODUCT WHERE MAC={mac}";
                string ycdMac = MethodWcf.ExecuteReturnSQLClient(sql);

                //查询产品是否为PT101
                sql = $"SELECT COUNT(*) FROM Device_Data WHERE MACAddr='{mac}' AND DeviceType like('PT101%')";
                string modemPt101 = MethodWcf.ExecuteReturnSQLClient(sql);

                if (string.IsNullOrEmpty(ycdMac) == false
                    && ycdMac.Length == 12)
                {
                    bool result;
                    if (modemPt101 != "1")
                        result = _ycdTel.SendAndRecv($"flash set ELAN_MAC_ADDR {ycdMac}", $"={ycdMac}", out _);
                    else
                        result = _ycdTel.SendAndRecv($"macaddr {ycdMac}", $"={ycdMac}", out _);

                    if (result == false)
                    {
                        AppendRichTextBox("写内部MAC失败");
                        return false;
                    }
                    else
                    {
                        AppendRichTextBox("写内部MAC成功");
                    }
                }
            }
#endif

            PROCESS processU = new PROCESS();
            processU.SetUpdate();
            processU.MAC = mac;
            processU.WORKER_ID = 88888888;
            processU.WORKER_NAME = "友创达";
            processU.FLOW_ID = 888;
            processU.LINE_ID = 8888;
            processU.STATION_ID = 8888;
            processU.TEST_RESULT = "Y";
            processU.START_TIME = DateTime.Now;
            processU.END_TIME = DateTime.Now;
            processU.NODE_ID = 88888;//专属的跳站
             MethodWcf.InsertProcessClient(processU);

            PRODUCT proW = new PRODUCT();
            proW.Clear();
            proW = new PRODUCT();
            proW.SetWhere(string.Format("MAC='{0}' OR YCD_MAC='{0}'", mac));
            proW.SetUpdate();
            proW.NODE_ID = _nodeId;
            proW.LINE_ID = 5016;
            proW.FLOW_ID = 117;
            //unbinding mac, add at 2019/4/21 15:55
            //proW.MAC = null;
            var updatePro = MethodWcf.UpdateProductClient(proW);


            if (updatePro.result) AppendRichTextBox("修改站位成功!!!\r\n修改站位成功!!!\r\n修改站位成功!!!\r\n修改站位成功!!!\r\n修改站位成功!!!");
            else AppendRichTextBox("修改站位失败!!!\r\n修改站位失败!!!\r\n修改站位失败!!!\r\n修改站位失败!!!\r\n修改站位失败!!!");

            return updatePro.result;
        }

        private bool RunCmd(CmdClass cmd, string mac)
        {
            if (string.IsNullOrEmpty(mac) || mac.Length != 12) return false;

            bool runRet = false;

            if (cmd.Type == "0")
            {
                //http协议
                string cmdKey = GetRealCmdStr(cmd.KeyWord, mac);
                runRet = GetModemMessage(cmd.CmdStr, cmdKey);

                AppendRichTextBox(string.Format("获取网页命令执行结果为：{0}", runRet));
            }
            else if (cmd.Type == "1")//执行TELNET命令
            {
                string cmdWord = GetRealCmdStr(cmd.CmdStr, mac);
                string cmdKey = GetRealCmdStr(cmd.KeyWord, mac);

                runRet = TelnetSendAndRecv(cmdWord, cmdKey);

                AppendRichTextBox(string.Format("TELNET命令执行结果为：{0}", runRet));
            }
            else if (cmd.Type == "2")//执行CMD
            {
                AppendRichTextBox("执行CMD命令中，最长时间30S");
                runRet = DoneProcess(cmd);

                AppendRichTextBox(string.Format("CMD命令执行结果为：{0}", runRet));
            }
            else if (cmd.Type == "3")//等待时间
            {
                int sleepTimes = 0;
                if (int.TryParse(cmd.CmdStr, out sleepTimes))
                {
                    AppendRichTextBox("等待时间：" + sleepTimes + "mS");
                    System.Threading.Thread.Sleep(sleepTimes);
                }
                runRet = true;
            }
            else if (cmd.Type == "4")//打印文字
            {
                AppendRichTextBox(cmd.CmdStr);
                runRet = true;
            }
            else if (cmd.Type == "5")//判断数据是否正确
            {
                //判断数据库数据和MAC是否正确
                string cmdWord = GetRealCmdStr(cmd.CmdStr, mac);
                string cmdKey = GetRealCmdStr(cmd.KeyWord, mac);
                if (cmdWord == cmdKey) runRet = true;

                AppendRichTextBox(string.Format("判断{0}是否相等，命令执行结果为：{1}", cmd.CmdStr, runRet));
            }

            return runRet;
        }

        /// <summary>
        /// 获取解析后的CMD指令
        /// </summary>
        /// <param name="cmdStr"></param>
        /// <returns></returns>
        private string GetRealCmdStr(string cmdStr, string mac)
        {
            string cmdWord = cmdStr;

            if (cmdStr.Contains("{") && cmdStr.Contains("}"))//解析MAC
            {
                int left = cmdStr.IndexOf('{');
                int right = cmdStr.IndexOf('}');

                string pd = cmdStr.Substring(left + 1, right - left - 1);
                string[] pds = pd.Split(',');

                int start = 0;
                int length = 0;

                if (pds.Length == 4 && pds[0] == "MAC"
                    && int.TryParse(pds[1], out start)
                    && int.TryParse(pds[2], out length))
                {
                    string partMac = mac.Substring(start, length).ToLower();
                    if (pds[3] == "U")
                    {
                        partMac = mac.Substring(start, length).ToUpper();
                    }

                    if (right == cmdStr.Length - 1)
                    {
                        cmdWord = cmdStr.Substring(0, left) + partMac;
                    }
                    else
                    {
                        cmdWord = cmdStr.Substring(0, left) + partMac + cmdStr.Substring(right + 1);
                    }
                }
                else if (pds.Length == 1 && _device != null)
                {
                    PropertyInfo info = (from p in _listInfo
                                         where p.Name == pds[0]
                                         select p).FirstOrDefault();

                    if (info != null)
                    {
                        if (right == cmdStr.Length - 1)
                        {
                            cmdWord = cmdStr.Substring(0, left) + info.GetValue(_device);
                        }
                        else
                        {
                            cmdWord = cmdStr.Substring(0, left) + info.GetValue(_device) + cmdStr.Substring(right + 1);
                        }
                    }
                }
            }

            return cmdWord;
        }

        private bool DoneProcess(CmdClass cmd)
        {
            try
            {
                //以空格区分命令与参数

                //执行CMD命令，命令方式为：iperf.exe, -s
                ProcessStartInfo startInfo = new ProcessStartInfo();
                startInfo.FileName = cmd.CmdStr.Substring(0, cmd.CmdStr.IndexOf(' '));
                startInfo.Arguments = cmd.CmdStr.Substring(cmd.CmdStr.IndexOf(' ') + 1);
                startInfo.UseShellExecute = false;
                startInfo.RedirectStandardInput = true;
                startInfo.RedirectStandardOutput = true;
                startInfo.RedirectStandardError = true;
                startInfo.CreateNoWindow = true;

                var p = Process.Start(startInfo);
                p.StandardInput.AutoFlush = true;

                var waitRes = p.WaitForExit(30000);
                if (waitRes == false)
                {
                    p.Kill();
                }

                string msg = p.StandardOutput.ReadToEnd();
                p.Close();
                AppendRichTextBox(msg);

                return waitRes && msg.Contains(cmd.KeyWord);
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrLogTxt("DoneProcess", "执行进程失败", ex.ToString());
                return false;
            }
        }

        private List<CmdClass> GetCmdClass(string fileStr)
        {
            if (string.IsNullOrEmpty(fileStr)) return null;
            string[] cmdLine = fileStr.Replace("\n", "").Split('\r');

            List<CmdClass> list = new List<CmdClass>();

            for (int i = 0; i < cmdLine.Length; i++)
            {
                string[] codes = cmdLine[i].Trim().Split(';');
                if (codes.Length == 3)
                {
                    //只有命令行的数量真确才执行下面的操作
                    CmdClass cmdc = new CmdClass();
                    cmdc.Type = codes[0];
                    cmdc.CmdStr = codes[1];
                    cmdc.KeyWord = codes[2];
                    cmdc.RunTimes = 1;
                    cmdc.Continue = "T";
                    list.Add(cmdc);
                }
                else if (codes.Length == 4)
                {
                    //只有命令行的数量真确才执行下面的操作
                    CmdClass cmdc = new CmdClass();
                    cmdc.Type = codes[0];
                    cmdc.CmdStr = codes[1];
                    cmdc.KeyWord = codes[2];
                    int times;
                    if (int.TryParse(codes[3], out times))
                    {
                        cmdc.RunTimes = times;

                    }
                    cmdc.Continue = "T";
                    list.Add(cmdc);
                }
                else if (codes.Length == 5)
                {
                    //只有命令行的数量真确才执行下面的操作
                    CmdClass cmdc = new CmdClass();
                    cmdc.Type = codes[0];
                    cmdc.CmdStr = codes[1];
                    cmdc.KeyWord = codes[2];

                    int times = 0;
                    if (int.TryParse(codes[3], out times))
                    {
                        cmdc.RunTimes = times;
                    }

                    cmdc.Continue = codes[4];
                    list.Add(cmdc);
                }
            }

            return list;
        }

        private int portOffset = DateTime.Now.Second;

        private void FormCmdTools_Move(object sender, EventArgs e)
        {
            this.Location = _localPoint;
        }

        /// <summary>
        /// 获取网页数据
        /// </summary>
        /// <returns></returns>
        private bool GetModemMessage(string url, string key)
        {
            try
            {
                //使用新的类YcdTelnetClass
                if (portOffset >= 800) portOffset = 0;
                portOffset++;

                int port = int.Parse(url.Substring(url.IndexOf(':') + 1, url.IndexOf('/') - url.IndexOf(':') - 1));


                HttpArgs httpArgs = new HttpArgs
                {
                    Url = url.Substring(url.IndexOf('/')),
                    Host = url.Substring(0, url.IndexOf('/')),
                    Cookie = ""
                };

                string httpMsg;
                bool hasKey = HttpBaseClass.GetHttpMsg(_localIp, _localPort + portOffset, _modemIp, port, httpArgs, key, out httpMsg);

                AppendRichTextBox(httpMsg);

                return hasKey;

            }
            catch (Exception ex)
            {
                AppendRichTextBox(ex.ToString());
                return false;
            }
        }


        private bool TelnetSendAndRecv(string cmdStr, string keyWord)
        {
            if (_ycdTel == null || _ycdTel.Connected == false)
            {
                if (portOffset >= 800) portOffset = 0;
                portOffset += 5;

                _ycdTel = new YcdTelnetSecond(_modemIp, _localIp, _localPort + portOffset);
                if (_ycdTel.Connect() == false)
                {
                    AppendRichTextBox("TELNET连接失败");
                    _ycdTel.Send("exit");
                    _ycdTel.Close();
                    _ycdTel = null;
                    return false;
                }
            }

            string msg;
            bool res = _ycdTel.SendAndRecv(cmdStr, keyWord, out msg, 8000);
            AppendRichTextBox(msg);

            return res;
        }

    }

}
